﻿<%@ WebHandler Language="C#" Class="callback_handler_demo" %>

/**
 * Copyright (C) 2011 Paycircuit.com, Thinking Spot
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */


using System;
using System.Web;
using System.Net;
//using System.Net.Mail; //uncomment as needed, used only for debug
using System.IO;
using paycircuit.com.google.iap;


public class callback_handler_demo : IHttpHandler
{
    //*** I M P O R T A N T ***
    //Change these to your Seller ID and Secret(key)
    //*************************
    const string MY_SELLER_SECRET =  "YOUR SELLER SECRET";
    const string MY_SELLER_ID =  "YOUR SELLER ID";
    //*************************

    const string MY_POSTBACK_TYP = "google/payments/inapp/item/v1/postback/buy"; //Value is CaSE-sEnsitive (strict verification of JWT).  
    const string THE_ISSUER = "Google"; //Value is CaSE-sEnsitive (strict verification of JWT).
    const bool STRICT_VERIFICATION = true; // True: strict verification of JWT, False: header/signature verification 


    public void ProcessRequest(HttpContext context)
    {
        if (context.Request.RequestType.ToLower() == "post" && context.Request.InputStream != null && context.Request.InputStream.Length > 0)
        {
            HttpRequest PostReq = HttpContext.Current.Request;

            if (PostReq.Form["jwt"] != null)
            {
                string _rawJWT = PostReq.Form["jwt"];

                if (STRICT_VERIFICATION)
                {
                    parseStrictJWT(_rawJWT, context);
                }
                else
                {
                    parseJWT(_rawJWT, context);
                }

            }
            else
            {
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; //http500
            }
        }
        else
        {
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; //http500
        }

        context.Response.End();
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    /// <summary>
    /// Parse and verify the JWT POST from Google (signature verification)
    /// </summary>
    /// <param name="jstring">JWT value</param>
    /// <param name="ctxt">Current HTTP context</param>
    private void parseJWT(string jstring, HttpContext ctxt)
    {
        string _jwtHeader = string.Empty;
        string _jwtClaim = string.Empty;

        //verify the JWT
        if (JWTHelpers.verifyJWT(jstring, MY_SELLER_SECRET, ref _jwtHeader, ref _jwtClaim))
        {

            try
            {
                //if the JWT is successfully verified (true), proceed to deserialize
                JWTHeaderObject HeaderObj = JSONHelpers.dataContractJSONToObj(_jwtHeader, new JWTHeaderObject()) as JWTHeaderObject;
                InAppItemObject ClaimObj = JSONHelpers.dataContractJSONToObj(_jwtClaim, new InAppItemObject()) as InAppItemObject;

                //You can do whatever you need to do with the data           
                parsePayload(ClaimObj, HeaderObj);

                //Respond http 200 and return google order id from jwt
                ctxt.Response.StatusCode = (int)HttpStatusCode.OK;
                ctxt.Response.ContentType = "text/plain";
                ctxt.Response.Write(ClaimObj.response.orderId);
            }
            catch (Exception e)
            {
                debug(jstring, e.Message);
                ctxt.Response.StatusCode = (int)HttpStatusCode.InternalServerError; //http500
            }
        }
        else
        {
            debug(jstring, "parseJWT Verification failure");
            ctxt.Response.StatusCode = (int)HttpStatusCode.InternalServerError; //http500
        }
    }

    /// <summary>
    ///Verifies values in header and payload (not just signuature matching).
    /// </summary>
    /// <param name="jstring">JWT value</param>
    /// <param name="ctxt">Current HTTP context</param>
    private void parseStrictJWT(string jstring, HttpContext ctxt)
    {
        JWTHeaderObject HeaderObj = null;
        InAppItemObject ClaimObj = null;

        if (JWTHelpers.verifyJWT(THE_ISSUER, MY_SELLER_ID, MY_POSTBACK_TYP, 1, jstring, MY_SELLER_SECRET, ref HeaderObj, ref ClaimObj))
        {
            try
            {
                //You can do whatever you need to do with the data    
                parsePayload(ClaimObj, HeaderObj);
                //Respond http 200 and return google order id from jwt
                ctxt.Response.StatusCode = (int)HttpStatusCode.OK;
                ctxt.Response.ContentType = "text/plain";
                ctxt.Response.Write(ClaimObj.response.orderId);
            }
            catch (Exception e)
            {
                debug(jstring, e.Message);
                ctxt.Response.StatusCode = (int)HttpStatusCode.InternalServerError; //http500
            }
        }
        else
        {
            debug(jstring, "parseStrictJWT Verification failure");
            ctxt.Response.StatusCode = (int)HttpStatusCode.InternalServerError; //http500
        }

    }


    //Sample
    private void parsePayload(InAppItemObject ClaimObj, JWTHeaderObject HeaderObj)
    {
        //header JWTHeaderObject
        string foo = string.Format("JWT Headers{0}JWT Algo: {1}{0}JWT kid: {2}{0}JWT typ: {3}{0}{0}", Environment.NewLine, HeaderObj.alg, HeaderObj.kid, HeaderObj.typ);

        //payload InAppItemObject
        string bar = string.Format("JWT Payload{0}JWT aud: {1}{0}JWT iss: {2}{0}JWT orderid: {3}{0}JWT sellerdata: {4}{0}JWT iat: {5}{0}" +
                "JWT itemName: {6}{0}JWT itemPrice: {7:c}{0}JWT Item Description: {8}{0}JWT exp: {9}{0}JWT typ: {10}{0}{0}", Environment.NewLine, ClaimObj.aud, ClaimObj.iss, ClaimObj.response.orderId, ClaimObj.request.sellerData, ClaimObj.iat,
                ClaimObj.request.name, ClaimObj.request.price, ClaimObj.request.description, ClaimObj.exp, ClaimObj.typ);

        debug(foo, bar);
    }

    //Sample
    private void debug(string str1, string str2)
    {
        /**Testing stuff
        * *****************************************************
        * MailMessage msg = new MailMessage { IsBodyHtml = false, Subject = "Google Code Test", Body = str1 + Environment.NewLine + Environment.NewLine + str2, From = new MailAddress("my_email@some_domain.com") };
        * msg.To.Add(new MailAddress("my_email@some_domain.com"));
        * SmtpClient smtp = new SmtpClient { Host = "my_mail_server", Port = 25 };
        * smtp.Send(msg);
        * *****************************************************           
        */

    }

   
}